package utils;


import java.sql.Timestamp;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.text.DateFormat;
import java.util.Locale;

import java.util.Calendar;
import java.util.GregorianCalendar;

import org.apache.commons.lang.time.DateFormatUtils;
import org.apache.commons.lang.time.DateUtils;
import org.apache.log4j.Logger;

/**
 * 日期工具类
 * @author admin
 *
 */


public class DateUtil {
	static Logger log = Logger.getLogger(DateUtil.class);
	private static String deaultDateFormat = "yyyy-MM-dd";
	
	
	/**
     * 格式化日期和时间，并按格式转换为字符串
     * 例：20040430172703
     * @param date 要格式化的日期
     * @return 返回日期和时间
     * @author zly
     */
    public static String formatDateTime1(Date date) {
    	if(date == null) {
    		return "";
    	}
    	SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        return sdf.format(date);
    }
    
    /**
     * 格式化日期和时间，并按格式转换为字符串
     * 例：20040430
     * @param String 要格式化的日期
     * @return 返回日期和时间
     * @author zly
     */
    public static Date formatStringTime(String  str){
    	SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMdd");
    	  Date date=null;
		try {
			date = dateFormat.parse(str);
		} catch (ParseException e) {
			e.printStackTrace();
		} 
    	  return date;
    }
    
    /**
     * 返回当前的小时
     * @return 当前小时
     */
    public static int getHour() {
    	GregorianCalendar gcNow = new GregorianCalendar();
    	return gcNow.get(GregorianCalendar.HOUR);
    }
    
    /**
     * 返回当前的分钟
     * @return int 返回当前的分钟
     */
    public static int getMinute() {
    	GregorianCalendar gcNow = new GregorianCalendar();
    	return gcNow.get(GregorianCalendar.MINUTE);
    }
    
    /**
     * 返回当前的秒数
     * @return int 第几秒
     */
    public static int getSecond() {
    	GregorianCalendar gcNow = new GregorianCalendar();
    	return gcNow.get(GregorianCalendar.SECOND);
    }
    
	/**
     * 返回今天是本月的第几天
     * @return 第几天
     */
    public static int getToDayOfMonth() {
        GregorianCalendar gcNow = new GregorianCalendar();
        return gcNow.get(GregorianCalendar.DAY_OF_MONTH);
    }
    
    /**
     * 返回今天是本年的第几周 
     * @return int 从1开始
     */
    public static int getToWeekOfYear() {
    	GregorianCalendar gcNow = new GregorianCalendar();
    	return gcNow.get(GregorianCalendar.WEEK_OF_YEAR);
    }
	
    /**
     * 返回本月
     * @return 本月
     */
    public static int getThisMonth() {
        GregorianCalendar gcNow = new GregorianCalendar();
        return gcNow.get(GregorianCalendar.MONTH) + 1;
    }
	
    /**
     * 返回当前年
     * @return 本年
     */
    public static int getThisYear() {
        GregorianCalendar gcNow = new GregorianCalendar();
        return gcNow.get(GregorianCalendar.YEAR);
    }
	
    /**
     * 返回一个当前的时间，并按格式转换为字符串
     * 例：17:27:03
     * @return 当前时间
     */
    public static String getNowTime() {
        GregorianCalendar gcNow = new GregorianCalendar();
        Date dNow = gcNow.getTime();
        DateFormat df = DateFormat.getTimeInstance(DateFormat.MEDIUM, Locale.SIMPLIFIED_CHINESE);
        return df.format(dNow);
    }
	
    /**
     * 返回一个当前日期，并按格式转换为字符串
     * 例：2004-4-30
     * @return 当前月份
     */
	public static String getNowDate() {
		return DateUtil.parseDateToString(new Date());
	}
	
    /**
     * 返回一个当前日期和时间，并按格式转换为字符串
     * 例：2004-4-30 17:27:03
     * @return 当前详细时间
     */
    public static String getNowDateTime() {
        GregorianCalendar gcNow = new GregorianCalendar();
        java.util.Date dNow = gcNow.getTime();
        DateFormat df = DateFormat.getDateTimeInstance(DateFormat.MEDIUM, DateFormat.MEDIUM, Locale.SIMPLIFIED_CHINESE);
        return df.format(dNow);
    }
    
    /**
     * 格式化日期和时间，并按格式转换为字符串
     * 例：2004-4-30 17:27:03
     * @param date 要格式化的日期
     * @return 返回日期和时间
     */
    public static String formatDateTime(Date date) {
    	if(date == null) {
    		return "";
    	}
    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
        return sdf.format(date);
    }
    
    /**
     * 按格式转换为字符串
     * 例：2004430 
     * @param date 要格式化的日期
     * @return 格式化后的日期 
     */
    public static String formatCardDate(Date date) {
    	SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMdd");
        return sdf.format(date);
    }
    /**
     * 格式转换为字符串
     * 例：2004-4-30 
     * @param date 要格式化的日期
     * @return 格式化后的日期
     */
    public static String formatDate(Date date) {
    	SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        return sdf.format(date);
    }
	
    /**
     * 返回日期和时间，并按格式转换为字符串
     * 例：2004-4-30 返回 04 
     * @param date 要格式化的日期
     * @return 月份
     */
    public static String formatDateMM(Date date) {
    	SimpleDateFormat sdf = new SimpleDateFormat("MM");
        return sdf.format(date);
    }
	
	/**
	 * 计算两日期之间的天数
	 * @param sd 起始日期，格式yyyy-MM-dd
	 * @param ed 终止日期，格式yyyy-MM-dd
	 * @return 天数
	 */
	public static long getIntervalDay(String sd, String ed) {
		return ((java.sql.Date.valueOf(ed)).getTime() - (java.sql.Date.valueOf(sd)).getTime()) / (3600 * 24 * 1000);
	}

	/**
	 * 计算两日期之间的月数
	 * @param startT 开始日期
	 * @param endT 结束日期
	 * @return int 月数
	 */
	public static int getIntervalMonth(String startT, String endT) {
		startT = formatDate(startT);
		endT = formatDate(endT);
		int i = Integer.parseInt(startT.substring(0, 4));
		int j = Integer.parseInt(endT.substring(0, 4));
		int i1 = Integer.parseInt(startT.substring(5, 7));
		int j1 = Integer.parseInt(endT.substring(5, 7));
		return (j - i) * 12 + (j1 - i1);
	}
	
	/**
	 * 计算两日期之间的年数
	 * @param startT 开始日期
	 * @param endT 结束日期
	 * @return int 年数
	 */
	public static int getIntervalYear(String startT, String endT) {
		startT = formatDate(startT);
		endT = formatDate(endT);
		int i = Integer.parseInt(startT.substring(0, 4));
		int j = Integer.parseInt(endT.substring(0, 4));
		return j - i;
	}
	
	/**
	 * 将yyyy-MM-dd类型的字符串转换为Date类型 如果字符串日期不合法
	 * @param str 需要转换的日期字符串
	 * @return 转换后的日期类型
	 */
	public static Date parseStringToDate(String str) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		try {
			return dateFormat.parse(str);
		} catch (Exception ex) {
			log.debug("DateUtils.java : " + ex.getMessage());
			return null;
		}
	}
	
	/**
	 * 将yyyy-MM-dd HH:MM:SS类型的字符串转换为Date类型 如果字符串日期不合法
	 * @param str 需要转换的日期字符串
	 * @return 转换后的日期类型
	 */
	public static Date parseStringToDateTime(String str) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
		try {
			return dateFormat.parse(str);
		} catch (Exception ex) {
			log.debug("DateUtils.java : " + ex.getMessage());
			return null;
		}
	}
	
	/**
	 * 将yyyyMMddHHMMSS类型的字符串转换为Date类型
	 * @param str 需要转换的日期字符串
	 * @return 转换后的日期
	 */
	public static Date parseStringToDateTime2(String str){
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyyMMddHHmmss");
		try {
			return dateFormat.parse(str);
		} catch (Exception ex) {
			log.debug("DateUtils.java : " + ex.getMessage());
			return null;
		}
	}
	
	/**
	 * 将Date类型数据转换为yyyy-MM-dd字符串
	 * @param date 需要转换的日期
	 * @return 转换后的字符串
	 */
	public static String parseDateToString(Date date) {
		return DateFormatUtils.ISO_DATE_FORMAT.format(date);
	}
	
	/**
	 * 得到指定日期的加，减天数后的字符串日期。
	 * @param str 指定的日期
	 * @param day 加减的天数
	 * @return 计算后的日期
	 */
	public static String getAddDays(String str, int day) {
		Date date = parseStringToDate(str);
		return parseDateToString(DateUtils.addDays(date, day));
	}
	
	
	/**
	 * 得到指定日期的加，减天数后的字符串日期。
	 * @param date 指定的日期
	 * @param day 加减的天数
	 * @return 计算后的日期
	 */
	public static Date getAddDays(Date date, int day) {
		return add(date,5,day);
	}
	
	/**
	 * 得到指定日期的加，减年数后的字符串日期。
	 * @param date 指定的日期
	 * @return 计算后的日期
	 */
	public static Date getAddYears(Date date, int year) {
		return add(date,1,year);
	}
	
	/**
	 * 得到指定日期的加，减星期数后的字符串日期。
	 * @param str 指定的日期
	 * @param week 加减的星期数
	 * @return 计算后的日期
	 */
	public static String getAddWeeks(String str, int week) {
		Date date = parseStringToDate(str);
		return parseDateToString(DateUtils.addWeeks(date, week));
	}
	
	/**
	 * 得到指定日期的加，减月数后的字符串日期。
	 * @param str 指定的日期
	 * @param month 加减的月数
	 * @return 计算后的日期
	 */
	public static String getAddMonths(String str, int month) {
		Date date = parseStringToDate(str);
		return parseDateToString(DateUtils.addMonths(date, month));
	}
	
	/**
	 * 得到指定日期加，减年数后的日期字符串。
	 * @param str 指定的日期
	 * @param year 加减的年数
	 * @return 计算后的日期
	 */
	public static String getAddYears(String str, int year) {
		Date date = parseStringToDate(str);
		return parseDateToString(DateUtils.addYears(date, year));
	}

	/**
	 * 功能：将日期转为标准格式YYYY-MM-DD
	 * @param String dt (YYYY-M-D,YYYY-M-DD,YYYY-MM-D)
	 * @return 格式化后的日期字符串
	 */
	public static String formatDate(String dt) {
		String retDt = "";
		try {
			if (null == dt || dt.length() == 0)
				return "";
			else {
				String year = "";
				String month = "";
				String date = "";
				int idx = dt.indexOf("-", 5);
				if (idx == -1)
					return "";
				year = dt.substring(0, 4);
				month = dt.substring(5, idx);
				if (month.length() == 1)
					month = "0" + month;
				date = dt.substring(idx + 1);
				if (date.length() == 1)
					date = "0" + date;
				retDt = year + "-" + month + "-" + date;
			}
			return retDt;
		} catch (Exception e) {
			return "";
		}
	}
	
	/**
	 * 比较两个时间字段日期大小(只比较到日)	 * 
	 * @param d1
	 * @param d2
	 * @return 如果想等返回0，如果d1大于d2返回1，如果小于返回-1
	 */
	public static int compareDate(Date d1, Date d2){
		short vl = 0;
    	GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(d1);
        int year = gc.get(GregorianCalendar.YEAR);
        int month = gc.get(GregorianCalendar.MONTH);
        int day = gc.get(GregorianCalendar.DAY_OF_MONTH);
        gc.setTime(d2);
        int tempYear = gc.get(GregorianCalendar.YEAR);
        int tempMonth = gc.get(GregorianCalendar.MONTH);
        int tempDay = gc.get(GregorianCalendar.DAY_OF_MONTH);
        if (year != tempYear) {
        	if (year>tempYear)
        		vl = 1;
        	else
        		vl = -1;
        }
        else {
        	if (month != tempMonth) {
        		if(month>tempMonth)
        			vl = 1;
        		else
        			vl = -1;
        	}
        	else {
        		if (day != tempDay) {
        			if (day > tempDay)
        				vl = 1;
        			else
        				vl = -1;
        		}
        	}
        }
        return vl;
	}
	 /**
     * 比较两日期字符串的大小
     * 如果想等返回2，如果d1大于d2返回0，如果小于返回2
     * @param d1
     * @param d2
     * @return (d1>d2)?2:(d1=d2)?1:0
     */
    public static int compareDate(String d1, String d2) {
    	short vl = 1;
    	GregorianCalendar gc = new GregorianCalendar();
        gc.setTime(parseStringToDate(d1));
        int year = gc.get(GregorianCalendar.YEAR);
        int month = gc.get(GregorianCalendar.MONTH);
        int day = gc.get(GregorianCalendar.DAY_OF_MONTH);
        gc.setTime(parseStringToDate(d2));
        int tempYear = gc.get(GregorianCalendar.YEAR);
        int tempMonth = gc.get(GregorianCalendar.MONTH);
        int tempDay = gc.get(GregorianCalendar.DAY_OF_MONTH);
        if (year != tempYear) {
        	if (year>tempYear)
        		vl = 2;
        	else
        		vl = 0;
        }
        else {
        	if (month != tempMonth) {
        		if(month>tempMonth)
        			vl = 2;
        		else
        			vl = 0;
        	}
        	else {
        		if (day != tempDay) {
        			if (day > tempDay)
        				vl = 2;
        			else
        				vl = 0;
        		}
        	}
        }
        return vl;
    }
    
	/**
	 * 功能：将Date类型数据转换为YYYY-mm-dd 字符串,如果传入的参数日期是1900-01-01 ,那么返回的字符串为""
	 * @param date  需要转换的日期
	 * @return 转换后的字符串
	 */
	public static String dateToStr(Date date) {
		String retDate = dateToOriStr(date);
		if (retDate.equals("1900-01-01"))
			retDate = "";

		return retDate;
	}

	/**
	 * 功能：将Date类型数据转换为yyyy-MM-dd字符串
	 * @param date  需要转换的日期
	 * @return 转换后的字符串
	 */
	public static String dateToOriStr(Date date) {
		if (date == null)
			return "1900-01-01";
		java.text.SimpleDateFormat dateFormat = new java.text.SimpleDateFormat(
				deaultDateFormat);

		return dateFormat.format(date);
	}

	/**
	 * 日期截取[去除时间部分]
	 * 例如: 将2008-06-10 00:00:00.0 转换为 2008-06-10
	 * @param parDateString 要截取的日期字符串
	 * @return  截取后的日期
	 */
    public static String getSubDateString(String parDateString) {
    	String str = "";
    	if (StrUtil.isNull(parDateString)) {
    		return str;
    	}
    	if (parDateString.length() == 10) {
    		return parDateString;
    	}
    	str = parDateString.substring(0, parDateString.indexOf(" "));
    	return str;
    }
    
    /**
     * 功能：将Date型转换为DateTimeStame型
     * @param date  需要转换的日期
     * @return 返回DateTimeStame类型的当前时间
     * @throws java.text.ParseException
     */
    public static Timestamp getCurrentTime(Date date){
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    	date = new Date();
    	Timestamp currentTime = null;
    	try{
    	  	currentTime = new Timestamp((new SimpleDateFormat(
			"yyyy-MM-dd HH:mm:ss")).parse(sdf.format(date)).getTime());
    	}
    	catch(Exception ex){
    		ex.printStackTrace();
    	}
        return currentTime;
    }
    
    /**
     * 日期的加法操作
     * @param date 日期
     * @param calendarField 类型，天，月，年
     * @param amount 增加的天数
     * @return 增加后的日期
     */
    public static Date add(Date date, int calendarField, int amount)
    {
        if(date == null)
        {
            throw new IllegalArgumentException("The date must not be null");
        } else
        {
            Calendar c = Calendar.getInstance();
            c.setTime(date);
            c.add(calendarField, amount);
            return c.getTime();
        }
    }
    
    /**
	 * 得到指定日期的加，减秒数后的日期。
	 * @param date 要格式化的日期
	 * @param sec 调整的秒数 
	 * @return 计算后的日期
	 */
	public static Timestamp getAddSec(Date date, int sec) {
		log.debug("-------getAddMin--------" + formatDateTime(date));
		SimpleDateFormat h = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss"); 
		String n = h.format(date); 
	  
		String myString = DateFormat.getDateInstance().format(date); 
		log.debug ("格式化后:"+myString); 
			  
		Timestamp time = Timestamp.valueOf(n); 
			  
		//加（减）秒数 
		long l = time.getTime()+sec*1000; 
		time.setTime(l); 
		return time;
	}
	/**
	 * 得到指定日期的加，减分钟数后的字符串日期。
	 * @param str 指定的日期
	 * @param day 加减的天数
	 * @return 计算后的日期
	 */
	public static Date getAddMin(Date str, int min) {
		
		return DateUtils.addSeconds(str, min);
	}
    /**
	 * 计算两日期之间的小时数
	 * @param sd 起始日期，格式yyyy-MM-dd HH:mm:ss
	 * @param ed 终止日期，格式yyyy-MM-dd HH:mm:ss
	 * @return 天数
	 */
	public static Float getIntervalHour(String sd, String ed) {
		DateFormat df = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		try
		{
		    Date d1 = df.parse(sd);
		    Date d2 = df.parse(ed);
		    
		    long diff = d2.getTime() - d1.getTime();
		    Float days = Float.parseFloat(String.valueOf(diff)) / (1000 * 60 * 60 );
		    days=(float)Math.round(days*10)/10;
		   	return days;
		}
		catch (Exception e)
		{
				return -1f;
		}
	}
	
	public static void main(String... args) {
//		log.debug(DateUtil.getIntervalDay("2008-1-2", "2008-2-2"));
//		log.debug(DateUtil.getIntervalMonth("2008-1-2", "2008-2-2"));
//		log.debug(DateUtil.getIntervalYear("2006-1-2", "2008-2-2"));
//		log.debug("2005-03-05 -> " + DateUtil.parseStringToDate("2005-03-05"));
//		log.debug("Now -> " + DateUtil.parseDateToString(new Date()));
//		log.debug("add day -> " + DateUtil.getAddDays("2005-6-5", 10));
//		log.debug("add month -> " + DateUtil.getAddMonths("2005-6-5", 10));
//		log.debug("add year -> " + DateUtil.getAddYears("2005-6-5", 10));
//		log.debug("add week -> " + DateUtil.getAddWeeks("2005-6-5", 10));
//		log.debug("NOW -> " + DateUtil.getNowDate());
//		log.debug("TIME -> " + DateUtil.getNowTime());
//		log.debug("DateAndTime -> " + DateUtil.getNowDateTime());
//		log.debug("Year -> " + DateUtil.getThisYear());
//		log.debug("Month -> " + DateUtil.getThisMonth());
//		log.debug("Day -> " + DateUtil.getToDayOfMonth());
//		log.debug("Hour -> " + DateUtil.getHour());
//		log.debug("Min ->" + DateUtil.getMinute());
//		log.debug("Sec -> " + DateUtil.getSecond());
//		log.debug("CompareDate -> " + DateUtil.compareDate("2008-3-6", "2008-3-6"));
//		log.debug("getSubDateString() : " + DateUtil.getSubDateString("2008-06-10 00:00:00.0"));
//		log.debug("getSubDateString() : " + DateUtil.getSubDateString(""));
		log.debug("现在: " + DateUtil.getNowDate());
		log.debug("比较: " + DateUtil.compareDate(DateUtil.getNowDate(), "2008-5-11"));
		System.out.println(parseStringToDateTime2("20141213125051"));
	
		
		
	}
	/**
	 * 将yyyy-MM-dd类型的字符串转换为Date类型 如果字符串日期不合法
	 * @param str 需要转换的日期字符串
	 * @return 转换后的日期类型
	 */
	public static Date parseStringToDate1(String str) {
		SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd");
		try {
			return dateFormat.parse(str);
		} catch (Exception ex) {
			System.out.println("DateUtils.java : " + ex.getMessage());
			return null;
		}
	}


/**
	 * 功能：将Date类型数据转换为YYYY-mm-dd 字符串,如果传入的参数日期是1900-01-01 ,那么返回的字符串为""
	 * @param date  需要转换的日期
	 * @return 转换后的字符串
	 */
	public static String dateToStr1(Date date) {
		String retDate = dateToOriStr(date);
		if (retDate.equals("1900-01-01"))
			retDate = "";

		return retDate;
	}
}
